package com.styletransfer.mapper;

import com.styletransfer.model.Work;
import org.apache.ibatis.annotations.*;

import java.util.List;

/**
 * 作品Mapper接口
 *
 * 这个接口定义了与作品表相关的数据库操作方法。
 * 使用MyBatis的注解方式，可以直接在接口方法上编写SQL语句。
 */
@Mapper
public interface WorkMapper {

    /**
     * 根据ID查询作品
     *
     * @param id 作品ID
     * @return 作品对象
     */
    @Select("SELECT * FROM work WHERE id = #{id}")
    Work findById(Long id);

    /**
     * 插入作品
     *
     * @param work 作品对象
     * @return 影响的行数
     */
    @Insert("INSERT INTO work(title, description, originalImage, resultImage, userId, styleId, " +
            "likeCount, commentCount, viewCount, isPublic, createTime, updateTime, status) " +
            "VALUES(#{title}, #{description}, #{originalImage}, #{resultImage}, #{userId}, #{styleId}, " +
            "#{likeCount}, #{commentCount}, #{viewCount}, #{isPublic}, #{createTime}, #{updateTime}, #{status})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insert(Work work);

    /**
     * 更新作品
     *
     * @param work 作品对象
     * @return 影响的行数
     */
    @Update("UPDATE work SET title = #{title}, description = #{description}, isPublic = #{isPublic}, " +
            "updateTime = #{updateTime} WHERE id = #{id}")
    int update(Work work);

    /**
     * 更新作品状态
     *
     * @param id 作品ID
     * @param status 新状态
     * @return 影响的行数
     */
    @Update("UPDATE work SET status = #{status}, updateTime = NOW() WHERE id = #{id}")
    int updateStatus(@Param("id") Long id, @Param("status") Integer status);

    /**
     * 增加作品浏览次数
     *
     * @param id 作品ID
     * @return 影响的行数
     */
    @Update("UPDATE work SET viewCount = viewCount + 1, updateTime = NOW() WHERE id = #{id}")
    int incrementViewCount(Long id);

    /**
     * 增加作品点赞数
     *
     * @param id 作品ID
     * @return 影响的行数
     */
    @Update("UPDATE work SET likeCount = likeCount + 1, updateTime = NOW() WHERE id = #{id}")
    int incrementLikeCount(Long id);

    /**
     * 减少作品点赞数
     *
     * @param id 作品ID
     * @return 影响的行数
     */
    @Update("UPDATE work SET likeCount = GREATEST(likeCount - 1, 0), updateTime = NOW() WHERE id = #{id}")
    int decrementLikeCount(Long id);

    /**
     * 增加作品评论数
     *
     * @param id 作品ID
     * @return 影响的行数
     */
    @Update("UPDATE work SET commentCount = commentCount + 1, updateTime = NOW() WHERE id = #{id}")
    int incrementCommentCount(Long id);

    /**
     * 减少作品评论数
     *
     * @param id 作品ID
     * @return 影响的行数
     */
    @Update("UPDATE work SET commentCount = GREATEST(commentCount - 1, 0), updateTime = NOW() WHERE id = #{id}")
    int decrementCommentCount(Long id);

    /**
     * 查询用户的作品
     *
     * @param userId 用户ID
     * @return 作品列表
     */
    @Select("SELECT * FROM work WHERE userId = #{userId} AND status = 1 ORDER BY id DESC")
    List<Work> findByUser(Long userId);

    /**
     * 分页查询用户的作品
     *
     * @param userId 用户ID
     * @param offset 偏移量
     * @param limit 限制数
     * @return 作品列表
     */
    @Select("SELECT * FROM work WHERE userId = #{userId} AND status = 1 ORDER BY id DESC LIMIT #{offset}, #{limit}")
    List<Work> findByUserPage(@Param("userId") Long userId, @Param("offset") Integer offset, @Param("limit") Integer limit);

    /**
     * 查询公开的作品
     *
     * @return 作品列表
     */
    @Select("SELECT * FROM work WHERE isPublic = 1 AND status = 1 ORDER BY id DESC")
    List<Work> findPublic();

    /**
     * 查询热门作品
     *
     * @param limit 限制数
     * @return 作品列表
     */
    @Select("SELECT * FROM work WHERE isPublic = 1 AND status = 1 ORDER BY likeCount DESC, viewCount DESC LIMIT #{limit}")
    List<Work> findHot(Integer limit);

    /**
     * 查询最新作品
     *
     * @param limit 限制数
     * @return 作品列表
     */
    @Select("SELECT * FROM work WHERE isPublic = 1 AND status = 1 ORDER BY createTime DESC LIMIT #{limit}")
    List<Work> findLatest(Integer limit);

    /**
     * 根据风格查询作品
     *
     * @param styleId 风格ID
     * @return 作品列表
     */
    @Select("SELECT * FROM work WHERE (styleId = #{styleId} OR styleId LIKE CONCAT(#{styleId}, ',%') OR styleId LIKE CONCAT('%,', #{styleId}) OR styleId LIKE CONCAT('%,', #{styleId}, ',%')) AND isPublic = 1 AND status = 1 ORDER BY id DESC")
    List<Work> findByStyle(Long styleId);

    /**
     * 分页查询作品
     *
     * @param offset 偏移量
     * @param limit 限制数
     * @return 作品列表
     */
    @Select("SELECT * FROM work WHERE isPublic = 1 AND status = 1 ORDER BY id DESC LIMIT #{offset}, #{limit}")
    List<Work> findByPage(@Param("offset") Integer offset, @Param("limit") Integer limit);

    /**
     * 统计作品总数
     *
     * @return 作品总数
     */
    @Select("SELECT COUNT(*) FROM work WHERE isPublic = 1 AND status = 1")
    Long count();

    /**
     * 统计用户作品总数
     *
     * @param userId 用户ID
     * @return 作品总数
     */
    @Select("SELECT COUNT(*) FROM work WHERE userId = #{userId} AND status = 1")
    Long countByUser(Long userId);

    /**
     * 分页查询风格相关作品
     *
     * @param styleId 风格ID
     * @param offset 偏移量
     * @param limit 限制数
     * @return 作品列表
     */
    @Select("SELECT * FROM work WHERE (styleId = #{styleId} OR styleId LIKE CONCAT(#{styleId}, ',%') OR styleId LIKE CONCAT('%,', #{styleId}) OR styleId LIKE CONCAT('%,', #{styleId}, ',%')) AND isPublic = 1 AND status = 1 ORDER BY id DESC LIMIT #{offset}, #{limit}")
    List<Work> findByStylePage(@Param("styleId") Long styleId, @Param("offset") Integer offset, @Param("limit") Integer limit);

    /**
     * 统计风格相关作品数量
     *
     * @param styleId 风格ID
     * @return 作品总数
     */
    @Select("SELECT COUNT(*) FROM work WHERE (styleId = #{styleId} OR styleId LIKE CONCAT(#{styleId}, ',%') OR styleId LIKE CONCAT('%,', #{styleId}) OR styleId LIKE CONCAT('%,', #{styleId}, ',%')) AND isPublic = 1 AND status = 1")
    Long countByStyle(Long styleId);

    /**
     * 根据多个风格ID查询作品（分页）
     *
     * @param styleIds 风格ID列表
     * @param offset 偏移量
     * @param limit 限制数
     * @return 作品列表
     */
    @Select("<script>" +
            "SELECT * FROM work WHERE " +
            "<foreach collection='styleIds' item='styleId' separator=' OR '>" +
            "(styleId = #{styleId} OR styleId LIKE CONCAT(#{styleId}, ',%') OR styleId LIKE CONCAT('%,', #{styleId}) OR styleId LIKE CONCAT('%,', #{styleId}, ',%'))" +
            "</foreach>" +
            " AND isPublic = 1 AND status = 1 ORDER BY id DESC LIMIT #{offset}, #{limit}" +
            "</script>")
    List<Work> findByStylesPage(@Param("styleIds") List<Long> styleIds, @Param("offset") Integer offset, @Param("limit") Integer limit);

    /**
     * 统计多个风格相关作品数量
     *
     * @param styleIds 风格ID列表
     * @return 作品总数
     */
    @Select("<script>" +
            "SELECT COUNT(*) FROM work WHERE " +
            "<foreach collection='styleIds' item='styleId' separator=' OR '>" +
            "(styleId = #{styleId} OR styleId LIKE CONCAT(#{styleId}, ',%') OR styleId LIKE CONCAT('%,', #{styleId}) OR styleId LIKE CONCAT('%,', #{styleId}, ',%'))" +
            "</foreach>" +
            " AND isPublic = 1 AND status = 1" +
            "</script>")
    Long countByStyles(@Param("styleIds") List<Long> styleIds);

    /**
     * 根据多个风格ID查询热门作品
     *
     * @param styleIds 风格ID列表
     * @param limit 限制数
     * @return 作品列表
     */
    @Select("<script>" +
            "SELECT * FROM work WHERE " +
            "<foreach collection='styleIds' item='styleId' separator=' OR '>" +
            "(styleId = #{styleId} OR styleId LIKE CONCAT(#{styleId}, ',%') OR styleId LIKE CONCAT('%,', #{styleId}) OR styleId LIKE CONCAT('%,', #{styleId}, ',%'))" +
            "</foreach>" +
            " AND isPublic = 1 AND status = 1 ORDER BY likeCount DESC, viewCount DESC LIMIT #{limit}" +
            "</script>")
    List<Work> findByStylesHot(@Param("styleIds") List<Long> styleIds, @Param("limit") Integer limit);

    /**
     * 检查用户是否对作品点赞
     *
     * @param userId 用户ID
     * @param workId 作品ID
     * @return 点赞记录数（大于0表示已点赞）
     */
    @Select("SELECT COUNT(*) FROM work_like WHERE userId = #{userId} AND workId = #{workId}")
    int isLiked(@Param("userId") Long userId, @Param("workId") Long workId);

    /**
     * 更新作品结果图片URL
     *
     * @param id 作品ID
     * @param resultImageUrl 新的结果图片URL
     * @return 影响的行数
     */
    @Update("UPDATE work SET resultImage = #{resultImageUrl}, updateTime = NOW() WHERE id = #{id}")
    int updateResultImage(@Param("id") Long id, @Param("resultImageUrl") String resultImageUrl);

    /**
     * 根据关键词搜索作品（分页）
     *
     * @param keyword 关键词
     * @param offset 偏移量
     * @param limit 限制数量
     * @return 作品列表
     */
    @Select("SELECT * FROM work WHERE (title LIKE CONCAT('%', #{keyword}, '%') " +
            "OR description LIKE CONCAT('%', #{keyword}, '%')) " +
            "AND isPublic = 1 AND status = 1 " +
            "ORDER BY id DESC LIMIT #{offset}, #{limit}")
    List<Work> findByKeyword(@Param("keyword") String keyword, @Param("offset") Integer offset, @Param("limit") Integer limit);

    /**
     * 根据关键词统计作品数量
     *
     * @param keyword 关键词
     * @return 作品数量
     */
    @Select("SELECT COUNT(*) FROM work WHERE (title LIKE CONCAT('%', #{keyword}, '%') " +
            "OR description LIKE CONCAT('%', #{keyword}, '%')) " +
            "AND isPublic = 1 AND status = 1")
    Long countByKeyword(@Param("keyword") String keyword);

    /**
     * 根据用户ID查询作品ID列表
     *
     * @param userId 用户ID
     * @return 作品ID列表
     */
    @Select("SELECT id FROM work WHERE userId = #{userId}")
    List<Long> findWorkIdsByUserId(Long userId);

    /**
     * 根据风格ID查询作品
     *
     * @param styleId 风格ID
     * @param limit 限制数量
     * @return 作品列表
     */
    @Select("SELECT * FROM work WHERE styleId = #{styleId} AND status = 1 AND isPublic = 1 " +
            "ORDER BY createTime DESC LIMIT #{limit}")
    List<Work> findByStyleId(Long styleId, Integer limit);

    /**
     * 根据关键词查询作品
     *
     * @param keyword 关键词
     * @param limit 限制数量
     * @return 作品列表
     */
    @Select("SELECT * FROM work WHERE (title LIKE CONCAT('%', #{keyword}, '%') " +
            "OR description LIKE CONCAT('%', #{keyword}, '%') " +
            "AND status = 1 AND isPublic = 1 " +
            "ORDER BY createTime DESC LIMIT #{limit}")
    List<Work> findByKeyword0(String keyword, Integer limit);

    /**
     * 根据多个风格ID查询作品
     *
     * @param styleIds 风格ID列表
     * @param limit 限制数量
     * @return 作品列表
     */
    @Select("<script>" +
            "SELECT * FROM work WHERE " +
            "<foreach collection='styleIds' item='styleId' separator=' OR '>" +
            "(styleId = #{styleId} OR styleId LIKE CONCAT(#{styleId}, ',%') " +
            "OR styleId LIKE CONCAT('%,', #{styleId}) " +
            "OR styleId LIKE CONCAT('%,', #{styleId}, ',%'))" +
            "</foreach>" +
            " AND status = 1 AND isPublic = 1 " +
            "ORDER BY createTime DESC LIMIT #{limit}" +
            "</script>")
    List<Work> findByStyleIds(@Param("styleIds") List<Long> styleIds, @Param("limit") Integer limit);
}
